<?php

namespace App\Services;

use App\Models\Robot;
use App\Models\Article;
use App\Models\RobotMessage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redis;

class RobotService extends BaseService
{
    /**
     * webhook的url key值
     */
    const WEBHOOK_URL = 'webhook_url';

    /**
     * 获取到推送的webhook的url地址
     * 优先从redis中获取，假如redis中不存在，则从数据库中读取
     * @return string|null
     */
    public function getWebhookUrl() : ?string
    {
        if (!Redis::exists(self::WEBHOOK_URL) || !($webhookUrl = Redis::get(self::WEBHOOK_URL))) {
            $webhookUrl = Robot::where('status', 1)
                ->value('webhook');

            if (empty($webhookUrl)) {
                return null;
            }

            Redis::set(self::WEBHOOK_URL, $webhookUrl);

        }

        return $webhookUrl;
    }

    /**
     * 获取到文章内容的信息
     * @param int $articleId
     * @return array
     */
    public function getArticle(int $articleId) : array
    {
        $article = Article::where('id',$articleId)
            ->first();

        return $article ? $article->toArray() : $article;
    }

    /**
     * 发送消息
     * @param int $articleId
     */
    public function sendRobot(int $articleId)
    {
        try {
            $webhookUrl = $this->getWebhookUrl();

            $article = $this->getArticle($articleId);

            if ( empty($webhookUrl)) {
                RobotMessage::create([
                    'article_id' => $articleId,
                    'content'    => json_encode($article),
                    'status'     => 0,
                    'message'    => '参数异常'
                ]);

                return ;
            }

            //判断消息发送类型
            if ($article['category'] == 1) {
                $response = Http::timeout(10)
                    ->post($webhookUrl,[
                        'msgtype'  => 'news',
                        'news' => [
                            'articles' => [
                                [
                                    'title'       => $article['title'],
                                    'description' => $article['description'],
                                    'url'         => $article['url'],
                                    'picurl'      => $article['picurl']
                                ]
                            ]
                        ]
                    ]);
            } else {
                $response = Http::timeout(10)
                    ->post($webhookUrl,[
                        'msgtype'  => 'markdown',
                        'markdown' => [
                            'content' => '## '.$article["title"]."\n\n".'>'.$article['description']
                        ]
                    ]);
            }

            if ($response->successful()) {
                $result = $response->json();

                if (is_array($result) && isset($result['errmsg']) && isset($result['errcode'])) {
                    RobotMessage::create([
                        'article_id' => $articleId,
                        'content'    => json_encode($article),
                        'status'     => $result['errmsg'] == 'ok' && $result['errcode'] == 0,
                        'message'    => $result['errmsg']
                    ]);

                    //发送完成后，当状态是立刻发送，或则指定的某个时间点
                    //将状态进行更新
                    if ($article['type'] == 'at_current' || $article['type'] == 'at_date') {
                        Article::where('id',$articleId)
                            ->update([
                                'status' => 1
                            ]);
                    }
                }
            }

            $response->throw();
        }catch (\Exception|\Error|\Throwable $exception) {
            Log::channel('api')
                ->emergency('机器人消息发送失败'.$exception->getMessage());

            RobotMessage::create([
                'article_id' => $articleId,
                'content'    => json_encode($article ?? []),
                'status'     => 1,
                'message'    => $exception->getMessage()
            ]);
        }
    }
}
